Skip to content

Conversation

@estebank
Copy link
Contributor

@estebank estebank commented Dec 21, 2025

When detecting "diff markers", inspect the current git repo's state to see if there is an active rebase. If that is the case, we try to identify whether the rebase is caused by git rebase or implicitly by git pull. In order to do that we query git to ask for the path of .git/rebase-merge and then inspect the files orig-head (the commit we are rebasing from), onto (the commit we are rebasing onto) and head-name (the branch being rebased). We modify the labels pointing at the markers to be clear on where each section of code is coming from.

git rebase case:

error: encountered diff marker
 --> src/main.rs:2:1
  |
2 | <<<<<<< HEAD
  | ^^^^^^^ between this marker and `=======` is the code that you're rebasing onto
3 |     println!("Hello, main!");
4 | =======
  | ------- between this marker and `>>>>>>>` is the code from branch 'branch-2' that you are rebasing
5 |     println!("Hello, branch!");
6 | >>>>>>> e644375 (branch)
  | ^^^^^^^ this marker concludes the conflict region
  |
  = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
          to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
  = note: for an explanation on these markers from the `git` documentation:
          visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>

git merge case:

error: encountered diff marker
 --> src/main.rs:2:1
  |
2 | <<<<<<< HEAD
  | ^^^^^^^ between this marker and `=======` is the code from branch 'branch-2'
3 |     println!("Hello, branch!");
4 | =======
  | ------- between this marker and `>>>>>>>` is the code from branch 'master'
5 |     println!("Hello, main!");
6 | >>>>>>> master
  | ^^^^^^^ this marker concludes the conflict region
  |
  = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
          to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
  = note: for an explanation on these markers from the `git` documentation:
          visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>

git pull --rebase case:

error: encountered diff marker
 --> src/main.rs:2:1
  |
2 | <<<<<<< HEAD
  | ^^^^^^^ between this marker and `=======` is the code from branch 'main'
3 |     println!("Hello, 2!");
4 | =======
  | ------- between this marker and `>>>>>>>` is the code from remote branch 'main' of github.com:estebank/pull-merge-conflict
5 |     println!("Hello, 1!");
6 | >>>>>>> 8191e7e4f9f82be45bdd4e71c37d2adcf4f88aa2
  | ^^^^^^^ this marker concludes the conflict region
  |
  = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
          to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
  = note: for an explanation on these markers from the `git` documentation:
          visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>

git pull --no-rebase case:

error: encountered diff marker
 --> src/main.rs:2:1
  |
2 | <<<<<<< HEAD
  | ^^^^^^^ between this marker and `=======` is the code from branch 'main' of github.com:estebank/pull-merge-conflict
3 |     println!("Hello, 1!");
4 | =======
  | ------- between this marker and `>>>>>>>` is the code from local branch 'main' before `git pull`
5 |     println!("Hello, 2!");
6 | >>>>>>> ebbeec7 (second)
  | ^^^^^^^ this marker concludes the conflict region
  |
  = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
          to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
  = note: for an explanation on these markers from the `git` documentation:
          visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>

Also, the generic help description is now removed.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 21, 2025
@rustbot
Copy link
Collaborator

rustbot commented Dec 21, 2025

r? @petrochenkov

rustbot has assigned @petrochenkov.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@estebank
Copy link
Contributor Author

estebank commented Dec 21, 2025

I'll push a run-make test for the different cases being handled shortly.

This is what it looks like in my two test repos

git rebase case:

Screenshot 2025-12-21 at 1 13 24 PM

git pull case:
Screenshot 2025-12-21 at 1 13 30 PM

and the current output:
Screenshot 2025-12-21 at 1 15 57 PM

Edit: done.

When detecting "diff markers", inspect the current `git` repo's state to see if there is an active rebase. If that is the case, we try to identify whether the rebase is caused by `git rebase` or implicitly by `git pull`. In order to do that we query `git` to ask for the path of `.git/rebase-merge` and then inspect the files `orig-head` (the commit we are rebasing from), `onto` (the commit we are rebasing onto) and `head-name` (the branch being rebased). We modify the labels pointing at the markers to be clear on where each section of code is coming from.

`git rebase` case:

```
error: encountered diff marker
 --> src/main.rs:2:1
  |
2 | <<<<<<< HEAD
  | ^^^^^^^ between this marker and `=======` is the code from branch `master` we're rebasing onto
3 |     println!("Hello, main!");
4 | =======
  | ------- between this marker and `>>>>>>>` is the code you had in branch `branch-2` that you are rebasing
5 |     println!("Hello, branch!");
6 | >>>>>>> e644375 (branch)
  | ^^^^^^^ this marker concludes the conflict region
  |
  = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
          to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
  = note: for an explanation on these markers from the `git` documentation:
          visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>
```

`git pull` case:

```
error: encountered diff marker
 --> src/main.rs:2:1
  |
2 | <<<<<<< HEAD
  | ^^^^^^^ between this marker and `=======` is the code from the remote branch `origin/main` we're rebasing onto
3 |     println!("Hello, 1!");
4 | =======
  | ------- between this marker and `>>>>>>>` is the code you had in branch `main` that you are rebasing
5 |     println!("Hello, 2!");
6 | >>>>>>> ebbeec7 (second)
  | ^^^^^^^ this marker concludes the conflict region
  |
  = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
          to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
  = note: for an explanation on these markers from the `git` documentation:
          visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>
```

Also, the generic `help` description had the `git pull` case flipped from what it should have been.
format!("code you had in commit `{orig_head_sha}` that you are rebasing");
}
if let Ok(output) =
Command::new("git").args(["branch", "--points-at", onto_sha.trim()]).output()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both calls to git branch --points-at (locals only and remotes) will incur a linear cost on the number of branches that exist in the repo. This can be a problem as there are some projects with lots of branches. We have the time cost of filtering them and the potential of lots branches pointing to the same tip, which is handled somewhat already.

The decision on whether the risk is acceptable, or we should not even try, is one I am flip-flopping and keep arguing with myself.

I reached out to the git mailing list to see if they could add the equivalent of branch-name so that this is unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to work only if the current directory cargo was invoked from is the root git repo and git has a default path configuration.

@Noratrieb Noratrieb added S-waiting-on-MCP Status: PR has a compiler MCP and is waiting for the compiler MCP to complete. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 23, 2025
The logic now only works if `cargo` is called from the git root, otherwise it won't find where the git metadata is. We rely purely on inspecting the files with rebase metadata and don't attempt to resolve a rebase target SHA to a branch name.

Reword slightly the labels.
@rustbot rustbot added the A-run-make Area: port run-make Makefiles to rmake.rs label Dec 23, 2025
@rust-log-analyzer

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-run-make Area: port run-make Makefiles to rmake.rs S-waiting-on-MCP Status: PR has a compiler MCP and is waiting for the compiler MCP to complete. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants